<template>
  <div>
    <lay-table
      v-model:columns="bak_columns"
      id="table_struct"
      v-model:dataSource="dataSource"
      :max-height="tableHeightMax"
    >
      <template v-slot:toolbar>
        <lay-row>
          <lay-col md="14">
            <h3>表：[{{targetTable}}]</h3>
          </lay-col>
          <lay-col md="5">
            <lay-input
                v-if="mode === 'scene'"
                v-model="filedName"
                placeholder="输入名称筛选"
                :maxlength="30"
                :allow-clear="true"
                @change="filterNameMethod"
                @clear="filterNameMethod"
                style="margin-right: 10px"
            ></lay-input>
          </lay-col>
          <lay-col md="3">
            <lay-icon
                :type="expandTable ? 'layui-icon-screen-restore' : 'layui-icon-screen-full'"
                @click="setTableHeight"
                style="margin-right: 5px;margin-left: 5px;color: #0d84ff"
            ></lay-icon>
            <lay-dropdown updateAtScroll placement="bottom-end">
              <lay-icon type="layui-icon-set" @click="modifyHead"></lay-icon>
              <template #content>
                  <lay-dropdown-menu>
                    <lay-dropdown-menu-item :key="item" v-for="item in my_head">
                      <lay-checkbox name="like" skin="primary"  v-model="item.vision" value="1" :label="item.title"></lay-checkbox>
                    </lay-dropdown-menu-item>
                  </lay-dropdown-menu>
              </template>
            </lay-dropdown>
            <lay-dropdown updateAtScroll  placement="bottom-end">
              <lay-icon type="layui-icon-slider" style="margin-left: 5px"></lay-icon>
              <template #content>
                <lay-card style="width: 250px">
                <lay-row space="10" style="margin-top: 10px">
                  <lay-col md="2"></lay-col>
                  <lay-col md="20">
                    <lay-button size="sm" type="normal" @click="addVision(false)">全不选</lay-button>
                    <lay-button size="sm" type="normal" @click="addVision(true)">全选</lay-button>
                    <lay-button size="sm" type="normal" @click="setDataSource">确定</lay-button>
                  </lay-col>
                </lay-row>
                <lay-row space="10" >
                  <lay-col md="24">
                    <lay-scroll height="240px" thumbColor="#000000">
                      <lay-dropdown-menu>
                        <lay-dropdown-menu-item :key="item" v-for="item in bak_dataSource">
                          <lay-checkbox
                              name="like"
                              skin="primary"
                              v-model="item.vision"
                              value="1"
                              :label="item.COLUMN_NAME"
                          ></lay-checkbox>
                        </lay-dropdown-menu-item>
                      </lay-dropdown-menu>
                    </lay-scroll>
                  </lay-col>
                </lay-row>
                </lay-card>
              </template>
            </lay-dropdown>
          </lay-col>
        </lay-row>
      </template>
      <template v-slot:my_id="{data}">
        <p style="margin-right: auto">
          <lay-icon style="font-size: 8px;height: 6px;color: #1E9FFF" type="layui-icon-up" @click="moveRow(data, 'up')"></lay-icon>
        </p>
        <p style="">
          <lay-icon style="font-size: 8px;height: 6px;color: #1E9FFF" type="layui-icon-down" @click="moveRow(data, 'down')"></lay-icon>
        </p>
      </template>
      <template v-slot:COLUMN_NAME="{data}">
        <lay-tooltip :content="getContent(data)" :is-dark="false" :disabled="mode !== 'scene'">
          <a style="color: blue;text-decoration: underline;">{{ data.COLUMN_NAME }}</a>
        </lay-tooltip>
      </template>
      <template v-slot:default_rule="{ data }" style="min-width: 600px">
        <lay-tooltip
            v-if="data.default_rule !== null"
            :visible="data.visible"
            trigger="click"
            :content="data.default_rule"
            :isDark="false"
        >
          <p
              class="rule-content"
              @mouseenter="data.visible=true"
              @mouseleave="data.visible=false"
          >{{ data.default_rule }}</p>
        </lay-tooltip>
        <div v-if="data.default_rule === null && mode === 'scene'">
          <lay-dropdown
              :trigger="['click', 'hover']"
              updateAtScroll
              placement="left"
          >
            <lay-input placeholder="尚未设置规则" style="width: 80%"></lay-input>
            <template #content>
              <HistoryRulesPage
                  :allowRelate="false"
                  :rowData="data"
                  :rules="historyRules"
                  @checkedRule="setRule"
                  @relateFields="relateOtherField"
              ></HistoryRulesPage>
            </template>
          </lay-dropdown>
        </div>
        <lay-button-group style="position: absolute;right: 2px;font-size: 20px" size="xs">
          <lay-button
            size="xs"
            @click="setFieldRules(data)"
          >
            <lay-icon type="layui-icon-set"></lay-icon>
          </lay-button>
          <lay-button
            size="xs"
            @click="deleteFieldRules(data)"
          >
            <lay-icon type="layui-icon-delete"></lay-icon>
          </lay-button>
        </lay-button-group>
      </template>
    </lay-table>
  </div>
</template>

<script lang="ts">
import {h, ref} from "vue";
import {layer} from "@layui/layui-vue";
import RuleDescription from "../Rules/RuleDescription.vue";

export default {
  name: "TableBasicInfo",
  components: {
      RuleDescription
  }
}
</script>

<script lang="ts" setup>
import {getCurrentInstance, h, onMounted, onUnmounted, reactive, ref, watch} from "vue";
import {layer} from "@layui/layui-vue";

import RuleDescription from "../Rules/RuleDescription.vue";
import {queryAllColumn} from "../../api/module/db";
import {clearDefaultRuleApi, setDefaultRuleApi} from "../../api/module/rule";
import {notify} from "../../untils/tip";
import {queryRuleHistoryApi, setRuleHistoryApi} from "../../api/module/scene";
import HistoryRulesPage from "./HistoryRules.vue";

// title <==> table
const tableInfo = reactive({data: {id: '', db_id: '', database: '', title: '', type: 'db_table'}});

const {mode, tableHeight, tableData} = defineProps({
    mode: {type: String, default: 'field'},  // 组件应用类型，场景页面 'scene' 或 数据库页面 'field'
    tableHeight: {type: String, default: ref('450px')},
    tableData: {type: Object, default: reactive({
        id: '',
        db_id: -1,
        database: '',
        table: '',
        column_rule:{
          columns: [],
          data_source: []
        }
    })
    }
});

const emit = defineEmits(["dependTable", "setEditFlag"]);
let instance = getCurrentInstance();

const eventListener: any = ref();
const filedName = ref('');
const expandTable = ref(true);
const tableHeightMax = ref('450px');
const tableHeightMin = ref('80px');
const historyRules = ref([]);

const setTableHeight = () => {
  expandTable.value =  !expandTable.value;
  if(expandTable.value){
    tableHeightMax.value = tableHeight;
  }else {
    tableHeightMax.value = tableHeightMin.value;
  }
}

const bak_columns: any = ref([]);
const my_head = ref([
    {"title": "排序", "width": "2%", "key": "my_id", "fixed": "left", "customSlot": "my_id", "vision": true},
    {"title": "名称", "width": "25%", "key": "COLUMN_NAME", "customSlot": "COLUMN_NAME", "vision": true},
    {"title": "备注", "width": "25%", "key": "COLUMN_COMMENT", "vision": true},
    {"title": "类型", "width": "12%", "key": "DATA_TYPE", "vision": true},
    {"title": "长度", "width": "3%", "key": "CHARACTER_MAXIMUM_LENGTH", "vision": true},
    {"title": "可空", "width": "3%", "key": "IS_NULLABLE", "vision": true},
    {"title": "默认值", "width": "10%", "key": "COLUMN_DEFAULT", "vision": true},
    {"title": "仿真规则", "width": "38%", "key": "default_rule", "customSlot": "default_rule", "fixed": "right", "vision": true}
]);

const my_head_scene = ref([
    {"title": "排序", "width": "2%", "key": "my_id", "fixed": "left", "customSlot": "my_id", "vision": true},
    {"title": "名称", "width": "25%", "key": "COLUMN_NAME", "customSlot": "COLUMN_NAME", "vision": true},
    {"title": "备注", "width": "25%", "key": "COLUMN_COMMENT", "vision": true},
    {"title": "类型", "width": "12%", "key": "DATA_TYPE", "vision": true},
    // {"title": "长度", "width": "3%", "key": "CHARACTER_MAXIMUM_LENGTH", "vision": true},
    // {"title": "可空", "width": "3%", "key": "IS_NULLABLE", "vision": true},
    // {"title": "默认值", "width": "10%", "key": "COLUMN_DEFAULT", "vision": true},
    {"title": "仿真规则", "width": "38%", "key": "default_rule", "customSlot": "default_rule", "fixed": "right", "vision": true}
]);

// 场景页面 只显示部分关机字段
const modifyHead = () => {
  if(mode === 'scene'){
    my_head.value.forEach((row) => {
      switch (row.key) {
        case 'CHARACTER_MAXIMUM_LENGTH': row.vision = false;break;
        case 'IS_NULLABLE': row.vision = false;break;
        case 'COLUMN_DEFAULT': row.vision = false;break;
        default: break;
      }
    })
  }
}

const getContent = (row: any) => {
    const content = ref('其他属性：字段长度：' + row.CHARACTER_MAXIMUM_LENGTH +
        '；可空：' + row.IS_NULLABLE + '；默认值：' + row.COLUMN_DEFAULT)
    return content.value;
}


watch(my_head.value, (newVlaue, oldValue) => {
  const temps = ref([]);
  newVlaue.forEach((unit)=>{
    if(unit.vision){
      temps.value.push(unit);
    }
  })
  bak_columns.value = temps.value;
},{immediate:true});

// 页面加载前要干的事情
onMounted(()=>{
  console.log('table basic info : ', tableData)
  tableHeightMax.value = tableHeight;
  if(mode === 'scene'){
    targetTable.value = tableData?.database + "." + tableData?.table;
    dataSource.value = tableData?.column_rule.data_source;
    bak_columns.value = my_head_scene.value;
    // eventListener.value = getCurrentInstance();
    instance?.proxy?.$Bus.on("on-relate-rule", (unit: any) => {
        console.log("on-relate-rule result:", unit);
        dataSource.value.forEach((row: any)=>{
          if(row.content === null && row.COLUMN_NAME === unit.name){
            setRule(row, unit);
          }
        })
    });
  }else {
    eventListener.value = getCurrentInstance();
    eventListener.value?.proxy?.$Bus.on("on-table", (res: any) => {
      console.log("on-table result:", res);
      // tableInfo.data = res;
      tableInfo.data = {id: res.id, db_id: res.dbLink, database: res.dbBase, title: res.name, type: 'db_table'}
      targetTable.value = res.dbBase + '.' + res.name;
      getTableColumn();
    });
    bak_columns.value = my_head.value;
  }
  bak_dataSource.value = dataSource.value;
  addVision(true);
});

const targetTable = ref('');
const columns = ref([]);
const dataSource: any = ref([])
const bak_dataSource = ref([]);

// 上下移动交互位置
const moveRow = (row: any, pos: string = 'down') => {
  const index = dataSource.value.indexOf(row);
  const length = dataSource.value.length;
  if(pos === 'up' && index !== 0){
    const before = dataSource.value[index-1];
    dataSource.value[index-1] = row;
    dataSource.value[index] = before;
  }else if(pos === 'down' && index !== length-1){
    dataSource.value[index] = dataSource.value[index+1];
    dataSource.value[index+1] = row;
  }else {
    notify('fail', '不能再移动了！')
  }
  emit("setEditFlag")
};

const filterNameMethod = () => {
  console.log('filterNameMethod:', filedName.value, bak_dataSource.value)
  bak_dataSource.value.forEach((unit:any)=>{
    if(filedName.value.length > 0){
      const regex_pattern = new RegExp(filedName.value, "i");
      const res = unit.COLUMN_NAME?.match(regex_pattern);
      // console.log("res:", res, filedName.value, unit)
      if(res !== null){
        unit.vision = true;
      }else {
        unit.vision = false;
      }
    }else {
      unit.vision = true;
    }
  })
  setDataSource();
}

const addVision = (flag: boolean) => {
  bak_dataSource.value.forEach((unit:any)=>{
    unit.vision = flag;
  })
};

const setDataSource = () => {
  const tempDS = ref([]);
  bak_dataSource.value.forEach((unit:any)=>{
    if(unit.vision){
      tempDS.value.push(unit);
    }
  })
  dataSource.value = tempDS.value;
};


// 设置规则
const setRule = (node: any, rule: any) => {
  console.log('setRule1:', node, rule);
  node.default_rule = rule.key;
  node.content = rule.value;
  node.describe_mode = rule.describe_mode;
  console.log('setRule2:', node, rule);
  const message = ref();
  message.value = targetTable.value + '.' + node.COLUMN_NAME + " 字段设置规则 " + node.default_rule + "成功！"
  notify("success", message.value)
}


// 一键关联规则到其他自动
const relateOtherField = (unit: any) => {
  console.log("on-relate-rule submit:", unit);
  instance?.proxy?.$Bus.emit('on-relate-rule', unit);
}

// 设置规则
const setHistoryRule = async (node: any) => {
    const params = reactive({describe_mode: node.describe_mode, content: node.content, name: node.COLUMN_NAME})
    let {result, status, message} = await setRuleHistoryApi(params);
    if(status === 'success'){
        historyRules.value = result;
    }else {
        layer.msg(message);
    }
}

const getTableColumn = async () => {
    const queryParams = reactive({
        id: tableInfo.data.id,
        database: tableInfo.data.database,
        table: tableInfo.data.title,
        db_id: tableInfo.data.db_id,
        current: 1,
        limit: 10
    })
    let {result, status, message} = await queryAllColumn(queryParams);
    if(status === 'success'){
        dataSource.value = result.data_source;
    }else {
        layer.msg(message);
    }
};

const deleteFieldRules = (node: any) => {
  const fieldName = tableData?.database + '.' + tableData?.table + '.' + node.COLUMN_NAME;
  layer.confirm("你确定要要删除此表字段 [" + fieldName + "]的规则么?",
  {
      btn: [
          {
              text: 'OK', callback: (id: number) => {
                  if(node.content && mode == 'field'){
                    clearDefaultRule(node);
                  }else if(node.content && mode == 'scene'){
                    node.describe_mode = null;
                    node.content = null;
                    node.default_rule = null;
                    emit("setEditFlag")
                  }else{
                    layer.msg('未关联规则，无需删除！')
                  }
                  layer.close(id);
              }
          },
          {
              text: 'Cancel', callback: (id: number) => {
                  layer.close(id);
              }
          }
      ]
  })
};

const clearDefaultRule = async (node: any) => {
  const targetDBCol = tableInfo.data.id + '.' + node.COLUMN_NAME;
  let {result, status, message} = await clearDefaultRuleApi({active_path: targetDBCol})
  layer.msg(message);
  if(status === 'success'){
    node.default_rule = '';
    node.content = null;
  }
};

// 数据源页面，用于设置 单个字段关联规则
const setFieldRuleMethod = async (node: any, res: any) => {
  const targetDBCol = tableInfo.data.id + '.' + node.COLUMN_NAME;
  console.log(targetDBCol);
  const params = reactive({
    describe_mode: 0,
    content: res.content,
    active_path_list: [targetDBCol]});
  console.log(params);
  let {result, status, message} = await setDefaultRuleApi(params);
  if(status !== 'success'){
    notify(status, message);
  }else {
    layer.close(tb_id.value);
  }
  return status;
};


const tb_id = ref();

const setFieldRules = (node: any) => {
  console.log('setFieldRules:', targetTable.value, node)
  const fieldName = targetTable.value + '.' + node.COLUMN_NAME;
  let cur_content;
  if(node.content){
    console.log(node.content)
    cur_content = node.content;
  }else {
    cur_content = reactive({});
  }
  // 若是场景页面调用，调用父组件方法来获取依赖表数据，将其保存到浏览器缓存中，方便子组件取用
  let scrollHeight: string = '30%';
  if(mode === 'scene'){
    emit('dependTable');
  }else if(mode === 'field'){
    node.describe_mode = 0;
  }
  console.log(cur_content);
  tb_id.value = layer.open({
    title: "【" + fieldName +"】设置仿真规则",
    // area: [lay_width, lay_height],
    content: h(RuleDescription, {
      disabled: false,
      addMode: true,
      mode: mode,
      scrollHeight: scrollHeight,
      describe_mode: node.describe_mode,
      content: cur_content,
      setDefaultRule: function (res: any) {
        console.log('setDefaultRule', mode, res);
        node.default_rule = res.content.defaultRule;
        node.content = res.content;
        node.describe_mode = res.describe_mode;
        if(mode === 'field'){
          setFieldRuleMethod(node, res);
        }else {
          emit("setEditFlag");
          notify('success', fieldName + '设置规则成功！');
        }
        setHistoryRule(node);
        layer.close(tb_id.value);
        return true;
      },
      cancelSetRule: function (){
        layer.close(tb_id.value);
      }
    }),
    maxmin: true,
    shade: false,
    min: (id: number) => {
        console.log(`最小化:${id}`)
    },
    full: (id: number) => {
        console.log(`最大化:${id}`)
    },
    restore: (id: number) => {
        console.log(`重置:${id}`)
    },
    success: (id: number) => {
        console.log(`成功:${id}`)
    }
  })
}

const submitTableData = () => {
  tableData.column_rule.columns = my_head;
  tableData.column_rule.dataSource = dataSource.value;
  return tableData;
}

// 暴露接口，提交数据给父组件
defineExpose({
  submitTableData
})

onUnmounted(() => {
  if(eventListener.value){
    eventListener.value?.proxy?.$Bus.off("on-table");
    eventListener.value?.proxy?.$Bus.all.clear();
  }
  if(instance !== null){
    instance.proxy.$Bus.off('on-relate-rule');
    instance.proxy.$Bus.all.clear();
  }
})

</script>

<style scoped>
.layui-icon .layui-icon-export{
  display: none;
}
.layui-icon .layui-icon-print{
  display: none;
}
.rule-content {
    width: 50%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space:nowrap;
    color: #01aaed;
}
</style>